package org.looop.studio.noots.document.handler;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.commons.lang.StringUtils;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.looop.studio.noots.document.DocumentHandler;
import org.looop.studio.noots.document.DocumentHandlerException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.w3c.tidy.Tidy;

public class JTidyHTMLHandler implements DocumentHandler {

	@Override
	public Document getDocument(InputStream is) throws DocumentHandlerException {
		Tidy tidy = new Tidy();
		tidy.setQuiet(true);
		tidy.setShowWarnings(false);
		org.w3c.dom.Document root;
		try {
			root = tidy.parseDOM(new InputStreamReader(is, "gbk"), null);
		} catch (UnsupportedEncodingException e) {
			throw new DocumentHandlerException(e);
		}
		Element rawDoc = root.getDocumentElement();
		Document doc = new Document();
		
		String title = getTitle(rawDoc);
		String body = getBody(rawDoc);
		
		if(StringUtils.isNotBlank(title)){
			doc.add(Field.Text("title", title));
		}
		
		if(StringUtils.isNotBlank(body)){
			doc.add(Field.Text("body", body));
		}
		return doc;
	}

	private String getBody(Element rawDoc) {
		if(rawDoc == null){
			return null;
		}
		String body = "";
		NodeList children = rawDoc.getElementsByTagName("body");
		if(children.getLength() > 0){
			body = getText(children.item(0));
		}
		return body;
	}

	private String getText(Node node) {
		NodeList children = node.getChildNodes();
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < children.getLength(); i++) {
			Node child = children.item(i);
			switch (child.getNodeType()) {
			case Node.ELEMENT_NODE:
				Element ele = (Element)child;
				if(StringUtils.equalsIgnoreCase(ele.getNodeName(), "script")){
					break;
				}
				sb.append(getText(child));
				sb.append(" ");
				break;
			case Node.TEXT_NODE:
				sb.append(((Text)child).getData());
				break;
			}
		}
		return sb.toString();
	}

	private String getTitle(Element rawDoc) {
		if(rawDoc == null){
			return null;
		}
		String title = "";
		NodeList children = rawDoc.getElementsByTagName("title");
		if(children.getLength() > 0){
			Element titleElement = (Element)children.item(0);
			Text text = (Text)titleElement.getFirstChild();
			if(text != null){
				title = text.getData();
			}
		}
		return title;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		DocumentHandler handler = new JTidyHTMLHandler();
		InputStream in = new FileInputStream("sample.htm");
		Document doc = handler.getDocument(in);
		System.out.println(doc);
	}

}
